package io.renren.modules.app.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.unionpay.sdk.AcpService;
import com.unionpay.sdk.SDKConfig;
import io.renren.common.utils.R;
import io.renren.common.utils.RedisUtils;
import io.renren.common.validator.ValidatorUtils;
import io.renren.modules.app.entity.OrderEntity;
import io.renren.modules.app.entity.PaymentLogEntity;
import io.renren.modules.app.entity.UserEntity;
import io.renren.modules.app.form.PayOrderForm;

import io.renren.modules.app.resolver.JsonParse;
import io.renren.modules.app.service.OrderService;
import io.renren.modules.app.service.PaymentLogService;
import io.renren.modules.app.service.UserBalanceService;
import io.renren.modules.app.service.UserService;
import io.renren.modules.app.utils.JwtUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/app/unionpay")
@Api("银联业务接口")
public class UnionPayController {
    @Autowired
    private SDKConfig config;
    @Autowired
    private AcpService acpService;
    @Value("${unionpay.mch-id}")
    private String mchId;
    @Value("${unionpay.fronturl}")
    private String frontUrl;
    @Value("${unionpay.backurl}")
    private String backUrl;
    @Value("${unionpay.orderurl}")
    private String orderUrl;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private UserService userService;
    @Autowired
    private OrderService orderService;
    /* @Autowired
private DepositLogService depositLogService;*/
    @Autowired
    private UserBalanceService userBalanceService;
    @Autowired
    private PaymentLogService paymentLogService;
    @Autowired
    private JwtUtils jwtUtils;


    @PostMapping("/nativePayOrder")
    @ApiOperation("native付款")
    public R nativePayOrder(@RequestBody PayOrderForm form, @RequestHeader HashMap header) {
        ValidatorUtils.validateEntity(form);
        String token = header.get("token").toString();
        Long userId = Long.parseLong(jwtUtils.getClaimByToken(token).getSubject());
        int orderId = form.getOrderId();
        UserEntity user = new UserEntity();
        user.setUserId(userId);
        QueryWrapper wrapper = new QueryWrapper(user);
        long count = userService.count(wrapper);
        if (count == 0){
            return R.error("用户不存在");
      }
        OrderEntity order = new OrderEntity();
        order.setUserId(userId.intValue());
        order.setId(orderId);
        order.setStatus(1);
        wrapper = new QueryWrapper(order);
        count = orderService .count(wrapper);
        if (count == 0) {
            return R.error("不是有效的订单");
        }
        order = new OrderEntity();
        order.setId(orderId);
        wrapper = new QueryWrapper(order);
        order = orderService .getOne(wrapper);
        String amount = order.getAmount().multiply(new BigDecimal("100")).intValue() + "";
        try {
            Map<String,String> requestData = new HashMap<String,String>();
            requestData.put("version","5.0.0");
            requestData.put("encoding","UTF-8");
            requestData.put("signMethod","01");
            requestData.put("txnType","01");
            requestData.put("txnSubType","01");
            requestData.put("bizType","00201");
            requestData.put("channelType","07");
            requestData.put("merId",mchId);
            requestData.put("accessType","@");
            requestData.put("orderId",order.getCode());
            requestData.put("txnTime",new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
            requestData.put("currencyCodr","156");
            requestData.put("txnAmt",amount);
            requestData.put("frontUrl",frontUrl);
            requestData.put("backUri",backUrl);
            requestData.put("paytimeout", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date().getTime() + 15 * 60 * 1000));
            Map<String,String> submitFromData = acpService.sign(requestData,"UTF-8");
            String requestFrontUrl = config.getFrontRequestUrl();
            //生成自动跳转的Html类单
            String htmlCode = AcpService.createAutoFormHtml(requestFrontUrl, submitFromData,"UTF-8");
            if (htmlCode!=null && htmlCode.length()>0){
                order.setPaymentType(3);
                UpdateWrapper updateWrapper = new UpdateWrapper();
                updateWrapper.eq("id",order.getId());
                orderService.update(order,updateWrapper);
                //解析ip地城
                String ip=header.get("ip").toString();
                String body = Jsoup.connect("http://api.lgp6.cn/ip?ip=" + ip).ignoreContentType(true).execute().body();
                System.out.println(body);
                JsonParse object = JSON.parseObject(body,JsonParse.class);

                PaymentLogEntity paymentLogEntity=new PaymentLogEntity();
                paymentLogEntity.setLocation(object.getData().getAddress());
                paymentLogEntity.setIp(ip);
                paymentLogEntity.setCode(order.getCode());
                paymentLogEntity.setAmount(order.getAmount());
                paymentLogEntity.setPaymentType(3);
                paymentLogService.save(paymentLogEntity);
                return R.ok().put("htmlCode", htmlCode);
            }else {
                return R.error("支付订单创建失败");
            }
        }catch (Exception e){
            e.printStackTrace();
            return R.error("银联支付模块故障");
        }
    }

    @RequestMapping("/recvFrontResponse")
    @ApiOperation("接受银联页面跳转请求")
    public  void  recvFrontResponse(HttpServletRequest request, HttpServletResponse response) throws Exception{
        request.setCharacterEncoding("UTF-8");
        HashMap<String,String> regParam = new HashMap<>();
        Enumeration<String> enumeration = request.getParameterNames();
        while (enumeration.hasMoreElements()){
            String name = enumeration.nextElement();
            String value = request.getParameter(name);
            regParam.put(name,value);
        }
        Map<String,String> valideData = null;
        String htmlCode = null;
        if (!regParam.isEmpty()){
            Iterator<Map.Entry<String, String>> it = regParam.entrySet().iterator();
            valideData =new HashMap<String,String>(regParam.size());
            while (it.hasNext()){
                Map.Entry<String, String> e = it.next();
                String key = (String) e.getKey();
                String value =(String) e.getValue();
                valideData.put(key, value);
            }
        }
        if (acpService.validate(valideData,"UTF-8")){
            System.out.println("前端回调签名验证成功");
            String respCode = request.getParameter("respCode");
            String queryId = request.getParameter("queryId");
            String code = request.getParameter("orderId");
            if ("00".equals(respCode)){
                UpdateWrapper updatewrapper = new UpdateWrapper();
                updatewrapper.eq("code",code);
                updatewrapper.set("status",2);
                updatewrapper.set("payment_type",3);
                updatewrapper.set("prepay_id",queryId);
                orderService.update(updatewrapper);
            }
        }
        response.sendRedirect(orderUrl);
    }

    @RequestMapping("/recvBackResponse")
    @ApiOperation("接收银联付款通知")
    public void recvBackResponse(HttpServletRequest request,HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("UTF-8");
        HashMap<String,String> reqParam = new HashMap<>();
        Enumeration<String> enumeration = request.getParameterNames();
        while (enumeration.hasMoreElements()){
            String name = enumeration.nextElement();
            String value = request.getParameter(name);
            reqParam.put(name,value);
        }
        Map<String,String> valideData = null;
        if (!reqParam.isEmpty()){
            Iterator<Map.Entry<String, String>> it = reqParam.entrySet().iterator();
            valideData =new HashMap<String,String>(reqParam.size());
            while (it.hasNext()){
                Map.Entry<String,String> e = it.next();
                String key = (String) e.getKey();
                String value = (String) e.getValue();
                value = new String(value.getBytes("UTF-8"),"UTF-8");
                valideData.put(key,value);
            }
        }
        if (!acpService.validate(valideData,"UTF-8")){
           //验签失败，需解决验签问题
            System.out.println("签名验证失败");
            response.setCharacterEncoding("UTF-8");
            Writer writer = response.getWriter();
            writer.write("签名验证失败");
            writer.close();
        }else{
            System.out.println("后端通知签名验证成功");
            String respCode = request.getParameter("respCode");
            String queryId = request.getParameter("queryId");
            String code = request.getParameter("orderId");
            if ("00".equals(respCode)){
                UpdateWrapper updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("code",code);
                updateWrapper.set("status",2);
                updateWrapper.set("payment_type",3);
                updateWrapper.set("prepay_id",queryId);
                orderService.update(updateWrapper);
            }
            response.setCharacterEncoding("UTF-8");
            Writer writer = response.getWriter();
            writer.write("ok");
            writer.close();
        }
    }
}
